/*
 * @Description: 穿梭框选中条目组件
 * @Author: Rfan
 * @Date: 2022-02-14 13:32:36
 * @LastEditTime: 2022-07-06 19:51:39
 */

import { useEffect, useMemo, useRef, useState } from 'react';
import { Button, Checkbox } from 'antd';
import cs from 'classnames';
import classNames from 'classnames/bind';
import { useDrag, useDrop, XYCoord } from 'react-dnd';
import { CheckboxChangeEvent } from 'antd/lib/checkbox';
import DataSettingDialog from '../../DataSetting';
import { useFolderTreeContext } from '../../../../contexts/FolderTreeContext';

import styles from '../styles/transferSelectItem.module.scss';

const cx = classNames.bind(styles);

const dragType = 'transferSelectItem';

const TransferSelectItem = (props: any) => {
  const {
    item,
    onItemSelect,
    selectedKeys,
    index,
    // onChange,
    moveSelect
  } = props;
  const { groupPlanAddProp } = useFolderTreeContext();

  // 数据设置弹窗状态
  const [dataSettingVisible, setDataSettingVisible] = useState(false);

  const [isSelected, setIsSelected] = useState(false);

  const ref = useRef<HTMLDivElement>(null);
  const [{ handlerId }, drop] = useDrop({
    accept: dragType,
    collect(monitor) {
      return {
        handlerId: monitor.getHandlerId()
      };
    },
    hover(hItem: any, monitor) {
      if (!ref.current) {
        return;
      }
      const dragIndex = hItem.index;
      const hoverIndex = index;

      // Don't replace items with themselves
      if (dragIndex === hoverIndex) {
        return;
      }

      // Determine rectangle on screen
      const hoverBoundingRect = ref.current?.getBoundingClientRect();

      // Get vertical middle
      const hoverMiddleY = (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2;

      // Determine mouse position
      const clientOffset = monitor.getClientOffset();

      // Get pixels to the top
      const hoverClientY = (clientOffset as XYCoord).y - hoverBoundingRect.top;

      // Only perform the move when the mouse has crossed half of the items height
      // When dragging downwards, only move when the cursor is below 50%
      // When dragging upwards, only move when the cursor is above 50%

      // Dragging downwards
      if (dragIndex < hoverIndex && hoverClientY < hoverMiddleY) {
        return;
      }

      // Dragging upwards
      if (dragIndex > hoverIndex && hoverClientY > hoverMiddleY) {
        return;
      }

      // Time to actually perform the action
      moveSelect(dragIndex, hoverIndex);

      // Note: we're mutating the monitor item here!
      // Generally it's better to avoid mutations,
      // but it's good here for the sake of performance
      // to avoid expensive index searches.
      hItem.index = hoverIndex;
    }
  });

  const [{ isDragging }, drag] = useDrag({
    type: dragType,
    item: () => {
      return { key: item.key, index };
    },
    collect: (monitor: any) => ({
      isDragging: monitor.isDragging()
    })
  });

  const opacity = isDragging ? 0 : 1;

  useEffect(() => {
    setIsSelected(selectedKeys.indexOf(item.key) >= 0);
  }, [selectedKeys]);

  drag(drop(ref));
  /**
   * @description: 必选复选框
   * @param {CheckboxChangeEvent} evt
   */
  const handleCheckboxChange = (evt: CheckboxChangeEvent) => {
    groupPlanAddProp(item, 'configRule', evt.target.checked);
    // onChange(true);
  };

  return (
    <div
      ref={ref}
      className={cs('ant-transfer-list-content-item', cx('item-wrap'))}
      style={{ opacity }}
      key={item.key}
      data-handler-id={handlerId}
      onClick={() => onItemSelect(item.key, !isSelected)}
    >
      <div className={cx('title')}>
        <div className={cx('checkbox-wrap')}>
          <Checkbox checked={isSelected} />
        </div>
        {item.field_desc || item.fieldDesc}
      </div>
      <div
        onClick={(evt) => {
          evt.stopPropagation();
        }}
      >
        <Checkbox checked={Boolean(item.configRule)} onChange={handleCheckboxChange} />
        <Button
          className={cx('setting-btn')}
          type="link"
          onClick={() => {
            setDataSettingVisible(true);
          }}
        >
          数据设置
        </Button>
        {useMemo(
          () => (
            <DataSettingDialog
              visible={dataSettingVisible}
              type={item.dict_type_id ? 1 : 2}
              field={item}
              onClose={() => {
                setDataSettingVisible(false);
              }}
            />
          ),
          [dataSettingVisible]
        )}
      </div>
    </div>
  );
};

export default TransferSelectItem;
